Once Off Payment Flow
Overview
This section of documentation will walk you through the payment flow from the inital trigger on the front end to the point of the transaction being finalized.
This process can be broken down into 20 steps
- The user places an order
- The Mini Program creates the order
- The order is created on the Mini Program server
- A pay order is created by the Mini Program Server
- And then on the VopdaPay App Server
- A payment URL is generated on the VodaPay App Server
- That payment URL is returned to the Mini Program Server
- And subsequently to the Mini Porgram
- The
my.tradePay
API is invoked by the Mini Program - A cashier is invoked by the App
- A query to get the pay order information is made
- The pay order information is then returned by the VopdaPay App Sever
- The pay order information is then displayed to the user
- The user checks and then pays the bill
- A request to hadle the payment is made to the VopdaPay App Server
- The payment is handled on the VopdaPay App Server
- The payment results are returned to the App
- The callback is invoked
- The notify URL is hit
- The order status is shown to the user
Payment flow sequence diagram
Create Order
On the Mini Program, a call to the /v2/payments/pay
endpoint needs to be made to intiate the payment flow
Request and Response snippet
Valid client-id
, request-time
and signature
values need to be supplied in the headers for the call to be successful
And the same paymentRequestId
cannot, successfully, be used on multiple calls
- Request
- Response
{
"productCode": "CASHIER_PAYMENT",
"salesCode": "51051000101000000011",
"paymentNotifyUrl": "http://mock.vision.vodacom.aws.corp/mock/api/v1/payments/notifyPayment.htm",
"paymentRequestId": "c0a83b17161398737179310015310",
"paymentRedirectUrl": "http://mock.vision.vodacom.aws.corp/mock/api/v1/payments/notifyPayment.htm",
"paymentExpiryTime": "3022-02-22T17:49:31+08:00",
"paymentAmount": {
"currency": "ZAR",
"value": "6234"
},
"order": {
"goods": {
"referenceGoodsId": "goods123",
"goodsUnitAmount": {
"currency": "ZAR",
"value": "6234"
},
"goodsName": "mobile1"
},
"env": {
"terminalType": "MINI_APP"
},
"orderDescription": "title",
"buyer": {
"referenceBuyerId": "216610000000259832353"
}
}
}
Request Parameters
productCode
<string | mandatory>
: (32 characters) For the purposes of Mini Programs CASHIER_PAYMENT
is the only valid value
salesCode
<string | mandatory>
: (32 characters)
paymentNotifyUrl
<string | optional>
: (1024 characters) The endpoint used to provide feedback on the status of the payment.
Note: Prior to a final production release this endpoint will have to be whitelisted on the VodaPay end. This process will be initated by one of our Project Mangers nearing the final release date
paymentRequestId
<string | mandatory>
: (64 characters) A unique identifier to identify a payment.
Note: This value is used to quey specific payments
paymentRedirectUrl
<string | optional>
: (1024 characters) Primarily used for recurring payments (payments scheduled to go off on a certain date for a certain period of time). Should you not be making use of recurring payments it is advised to populate this field with the same value as the one in paymentNotifyUrl
paymentExpiryTime
<string/datetime> | optional>
: (ISO 8601 standard) The time at which a payment attempt will no longer be considered valid
Note: This value should not be less than the current time. Failed or cancelled payments can be retried using the same paymentRequestId up until this time is reached. Should a payment be cancelled or fail a notification will only be sent out at this time
paymentAmount
<object | mandatory>
currency
<string | mandatory>
: (32 characters) At this point in timeZAR
is the only valid currencyvalue
<string | mandatory>
: (32 characters) The value of the payment in cents Note The value cannot be zero or less than zero.
order
<object | mandatory>
goods
<object | optional>
: Metedata to describe the payment Note: Details provided here will not affect the payment, however, it is recommeded that the values and information supplied here, if any, be validreferenceGoodsId
<string | optional>
: An identifier for the goods/services being purchasedgoodsUnitAmount
<object | optional>
: The units of goods purchasedcurrency
<string | optional>
: The currency usedvalue
<string | optional>
: The value in cents
goodsName
<string | optional>
: The name of the goods
env
<object | optional>
terminalType
<string | optional>
: At this point in timeMINI_APP
is the only valid value
orderDescription
<string | optional>
: A brief description of the orderbuyer
<object | optional>
referenceBuyerId
<string | optional>
: The customers userId Note: Should the ID provided here not align with the user logged onto the App the payment will fail
{
"result": {
"resultStatus": "A",
"resultCode": "ACCEPT",
"resultMessage": "ACCEPT."
},
"paymentId": "20210222111212800100166353500084689",
"redirectActionForm": {
"redirectUrl": "https://vodapay-m.sandbox.vfs.africa/m/portal/cashier/checkout?bizNo=20210222111212800100166353500084689×tamp=1664892542828&mid=216620000000179991384&sign=PzonPP8BdHkF3dGHmv5Z8XlZ%2BxIb5xQmNu%2BwBJGLZ85ZJOvqB65w817bzpjRSZ57dXUE7njpwzSutBrNKA1LUmAlCBEuAa5RVyrV9Yg7l5s6cRnxI062rDNThYr5bLK5vg1naTFVHOR7nHwJQoTMzG1XNho%2B%2FTKqw2vp25yShQCqgxHL8K%2BL7%2BK%2BGq6hRqmXkwPGJ4QI3iXOZkZaW8xlRfqCpsy%2F%2F6VDVJDCwlzu4Yfr29j%2FTDv42SwEsVqz1WsuBzoz9mw%2F8dAgBByZkR78eKBH0SPNYNYuAg%2FDJqqKQuth0YEz%2BZkb0JmDFE%2BXcgDWsqlb1VxmqpePqGTwp1gqAQ%3D%3D"
}
}
Response Parameters
result
<object>
resultStatus
<string>
: GIves the result status. One of four values S: success, A: accepted, F: Failed and U: unknownresultCode
<string>
: A string giving more details on the restuls statusresultMessage
<string>
: A brief description of the result code
paymentId
<string>
: A unique identifier for the payment
redirectActionForm
<object>
redirectUrl
<string>
: A redirct URL meant to be supplied to themy.tradePay
invocation
Result Codes
resultStatus
: This key will have one of four values:
- S: The transaction was successful. Note that this simply means that the update transaction was successful not that the funds have been transfered
- A: The transaction has already been accepted, at this point the next step in the payment flow needs to be started
- F: The transaction failed. The
resultCode
can be used to get more information - U: An unknown exception occured, the
resultCode
may be able to provide more details
Unknown exception codes
- UNKNOWN_EXCEPTION: The API call failed and the reason for it is unknown
- REQUEST_TRAFFIC_EXCEED_LIMIT: The request traffic exeecds the predefined limit
- PAYMENT_IN_PROCESS: The payment is being processed
Failed transaction codes
- REPEAT_REQ_INCONSISTENT: The request is a repeated request Ensure the
paymentRequestId
is unique - PROCESS_FAIL: A general business error occured Do not retry
- INVALID_API: The API called is invalid or inactive Ensure that you are calling the correct API
- PARAM_ILLEGAL: The parameters supplied are invalid Ensure that all values supplied are of the correct data type and in the correct format
- ACCESS_DENIED: Access is denied
- PAYMENT_AMOUNT_EXCEED_LIMIT: Payment amount exceeds limit
- USER_NOT_EXIST: The user does not exist
- USER_STATUS_ABNORMAL: The user status is abnormal
- USER_BALANCE_NOT_ENOUGH: The user has insufficient funds
- PARTNER_NOT_EXIST: The partner does not exist
- RISK_REJECT: Risk Reject
- CURRENCY_NOT_SUPPORT: The currecy supplied is not supported
- ORDER_STATUS_INVALID1: The order is in an invalid state, such as closed
- INVALID_ACCESS_TOKEN: The access token provided is invalid
- USER_AMOUNT_EXCEED_LIMIT: The payment amount exceeds the users amount limit
- EXPIRED_ACCESS_TOKEN: The access token provided has expired
- AUTH_CODE_ALREADY_USED: the auth code supplied has already been used
- INVALID_CODE: The auth code supplied is invalid
- EXPIRED_AGENT_TOKEN: The min program access token has expired
- INVALID_AGENT_TOKEN: The Mini Program access token is invalid
- INVALID_AUTH_CLIENT: The auth client ID is invalid
my.tradePay
The my.tradePay
API call initiates the payment process after all of the supporting information has been suppiled to the /v2/payments/pay
endpoint and a redirectURL has been return. The redirectURL is supplied as the paymentUrl
in the my.tradePay
call.
Sample Code
my.tradePay({
paymentUrl: 'https://....', // supply the redirectURL returned by /v2/payments/pay call
success: (res) => {
my.alert({
content: JSON.stringify(res)
});
},
fail: (res) => {
my.alert({
content: JSON.stringify(res)
});
}
});
Result Codes
"9000": Payment Successful
"8000": Payment is being processed
"6001": Payment failed
"4000": Payment cancelled
Payment notification
Please note that a successful response from my.tradePay
simply means that the payment has successfully been sent to the backend for validation and further processing. A request to the notification URL supplied in the /v2/payments/pay
call will be made on average after two minutes. Should that request be successful it is at this point that goods and/or services should be provisioned as the funds have been transferred.
Note The notification URL supplied will continue to be polled up until acknowledgement of the notifaction has been suppiled. Acknowledgement entails responding in the manner expected
This request will be sent to the URL you supplied in the /v2/payments/pay
call, the response section shows the expected responses
- Request
- response
{
"paymentId": "201911271907410100070000009999",
"paymentRequestId": "2019112719074101000700000088881",
"paymentAmount": {
"currency": "ZAR",
"value": "10000"
},
"paymentTime": "2019-11-27T12:02:01+08:30",
"paymentResult": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "success"
},
"retrievalReferenceNumber": "122909bah5ex",
"paymentMethod": [
{
"tenderType": "00",
"transactionId": "094a70a3-5843-4c70-b678-024dc1825426",
"value": "10000"
}
]
}
{
"paymentId": "201911271907410100070000009999",
"paymentRequestId": "2019112719074101000700000088881",
"paymentAmount": {
"currency": "ZAR",
"value": "10000"
},
"paymentCreateTime": "2019-11-27T12:01:01+08:30",
"paymentTime": "2019-11-27T12:02:01+08:30",
"paymentResult": {
"resultCode": "PROCESS_FAIL",
"resultStatus": "F",
"resultMessage": "A general business failure occurred. Don't retry."
},
"retrievalReferenceNumber": "122909bah5ex"
}
paymentId
<string | required>
: (64 characters) A unique identifier ofr the payment generated by VodaPay
paymentRequestId
<string | required>
: (64 characters) A unique identifier ofr the payment generated by the merchant
paymentAmount
<object | optional>
currency
<string | required>
: The currency of the paymentvalue
<string | optional>
: The amount of the payment in cents
paymentCreateTime
<string/>Datetime | optional>
: (ISO 8601 standard) The time when the payment succeeded
paymentTime
<string/Datetime | optional>
: (ISO 8601 standard) The time when the payment was created
paymentResult
<object | optional>
resultCode
<string | optional>
: The payment result coderesultStatus
<string | optional>
: Thestatus of the paymentresultMessage
<string | optional>
: A brief description of the result
retrievalReferenceNumber
<string | optional>
: The refernce number used on the SMME protal
{
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "success"
}
}
{}
An empty object should be returned as acknowledgement of the payment failure
result
<object | optional>
resultCode
<string | optional>
: The payment result coderesultStatus
<string | optional>
: Thestatus of the paymentresultMessage
<string | optional>
: A brief description of the result